﻿using System;
using System.Data;using THSERP.BusinessEntities;using THSERP.BaseProvider;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Transactions;
using THSLib;using THSERP.BaseProvider;

namespace THSERP.Modules.Transfer
{
    public class TransferEntities : ERPModuleEntities
    {
        #region Declare Constant
        public readonly static String strICTransfersObjectName = "ICTransfers";

        public readonly static String strICTransferItemsObjectName = "ICTransferItems";
        //stock from
        public const string cstFK_ICInventoryStockIDLabelControlFrom = "fld_lblFK_ICFromStockID";
        public const string cstICInventoryStockQtyLabelControlFrom = "fld_lblICInventoryStockQtyFrom";
        public const string cstICInventoryStockSOQtyLabelControlFrom = "fld_lblICInventoryStockSOQtyFrom";
        public const string cstICInventoryStockPOQtyLabelControlFrom = "fld_lblICInventoryStockPOQtyFrom";
        public const string cstICInventoryStockAvailableQtyLabelControlFrom = "fld_lblICInventoryStockAvailableQtyFrom";
        public const string cstICProductStkUOMLabelControlFrom = "fld_lblICProductStkUOMFrom";
        //stock To
        public const string cstFK_ICInventoryStockIDLabelControlTo = "fld_lblFK_ICToStockID";
        public const string cstICInventoryStockQtyLabelControlTo = "fld_lblICInventoryStockQtyTo";
        public const string cstICInventoryStockSOQtyLabelControlTo = "fld_lblICInventoryStockSOQtyTo";
        public const string cstICInventoryStockPOQtyLabelControlTo = "fld_lblICInventoryStockPOQtyTo";
        public const string cstICInventoryStockAvailableQtyLabelControlTo = "fld_lblICInventoryStockAvailableQtyTo";
        public const string cstICProductStkUOMLabelControlTo = "fld_lblICProductStkUOMTo";
        //transit stock
        public const string cstFK_ICInventoryStockIDLabelControlTrans = "fld_lblFK_ICTransitStockID";
        public const string cstICInventoryStockQtyLabelControlTrans = "fld_lblICInventoryStockQtyTrans";
        public const string cstICInventoryStockSOQtyLabelControlTrans = "fld_lblICInventoryStockSOQtyTrans";
        public const string cstICInventoryStockPOQtyLabelControlTrans = "fld_lblICInventoryStockPOQtyTrans";
        public const string cstICInventoryStockAvailableQtyLabelControlTrans = "fld_lblICInventoryStockAvailableQtyTrans";
        public const string cstICProductStkUOMLabelControlTrans = "fld_lblICProductStkUOMTrans";
        //all
        public const string cstFK_ICInventoryStockIDAllLabelControl = "fld_lblFK_ICStockIDAll";
        public const string cstICInventoryStockQtyAllLabelControl = "fld_lblICInventoryStockQtyAll";
        public const string cstICInventoryStockSOQtyAllLabelControl = "fld_lblICInventoryStockSOQtyAll";
        public const string cstICInventoryStockPOQtyAllLabelControl = "fld_lblICInventoryStockPOQtyAll";
        public const string cstICInventoryStockAvailableQtyAllLabelControl = "fld_lblICInventoryStockAvailableQtyAll";
        public const string cstICProductStkUOMAllLabelControl = "fld_lblICProductStkUOMAll";
        //stock from
        #endregion

        #region Declare all entities variables
        private ICTransfersInfo _iCTransfersObject;
        private ICTransferItemsInfo _iCTransferItemsObject;

        public THSItemsEntityList<TransferItemsEntity> lstICTransferItems;
        public THSList<ICTransferItemsInfo> lstICReferenceTransferItems;
        public THSList<ICTransfersInfo> lstICTransfers;
        #endregion

        #region Public Properties
        public ICTransfersInfo ICTransfersObject
        {
            get
            {
                return _iCTransfersObject;
            }
            set
            {
                _iCTransfersObject = value;
            }
        }
        public ICTransferItemsInfo iCTransferItemsObject
        {
            get
            {
                return _iCTransferItemsObject;
            }
            set
            {
                _iCTransferItemsObject = value;
            }
        }

        public THSItemsEntityList<TransferItemsEntity> ICTransferItemsList
        {
            get
            {
                return lstICTransferItems;
            }
            set
            {
                lstICTransferItems = value;
            }
        }
        public THSList<ICTransfersInfo> ICTransfersList
        {
            get
            {
                return lstICTransfers;
            }
            set
            {
                lstICTransfers = value;
            }
        }
        public THSList<ICTransferItemsInfo> ICReferenceTransferItemsList
        {
            get
            {
                return lstICReferenceTransferItems;
            }
            set
            {
                lstICReferenceTransferItems = value;
            }
        }

        #endregion

        #region Constructor
        public TransferEntities()
            : base()
        {
            _iCTransfersObject = new ICTransfersInfo();

            _iCTransferItemsObject = new ICTransferItemsInfo();

            lstICTransferItems = new THSItemsEntityList<TransferItemsEntity>();
            lstICReferenceTransferItems = new THSList<ICTransferItemsInfo>();
            lstICTransfers = new THSList<ICTransfersInfo>();
        }

        #endregion

        #region Init Main Object,Module Objects functions
        public override void InitMainObject()
        {

            MainObject = ICTransfersObject;
        }

        public override void InitModuleObjects()
        {
            ModuleObjects.Add("ICTransferItems", iCTransferItemsObject);
        }

        public override void InitModuleObjectList()
        {
            lstICTransferItems = new THSItemsEntityList<TransferItemsEntity>();
            lstICTransferItems.InitTHSList(
                                            this,
                                            THSUtil.GetTableNameFromBusinessObjectType(typeof(ICTransfersInfo)),
                                            THSUtil.GetTableNameFromBusinessObjectType(typeof(ICTransferItemsInfo)));
            lstICReferenceTransferItems = new THSList<ICTransferItemsInfo>();
            lstICReferenceTransferItems.InitTHSList(
                                            this,
                                            THSUtil.GetTableNameFromBusinessObjectType(typeof(ICTransfersInfo)),
                                            THSUtil.GetTableNameFromBusinessObjectType(typeof(ICTransferItemsInfo)));
            lstICTransfers = new THSList<ICTransfersInfo>();
            lstICTransfers.InitTHSList(this, String.Empty, THSUtil.GetTableNameFromBusinessObjectType(typeof(ICTransfersInfo)));
        }

        public override void InitGridControlInTHSList()
        {
            lstICTransferItems.InitTHSListGridControl();
            lstICTransfers.InitTHSListGridControl("fld_dgcICTransfers");
        }

        public override void SetDefaultModuleObjectsList()
        {
            try
            {
                lstICTransferItems.SetDefaultListAndRefreshGridControl();
                lstICTransfers.SetDefaultListAndRefreshGridControl();
            }
            catch (Exception)
            {
                return;
            }
        }

        #endregion

        #region Invalidate Module Objects functions


        public override void InvalidateModuleObjects(int iObjectID)
        {
            ICTransferItemsList.Invalidate(iObjectID);
        }


        #endregion

        #region Save Module Objects functions

        public override void SaveModuleObjects()
        {
            ICTransferItemsList.SaveItemObjects(true);
        }

        #endregion

        public override void SetValuesAfterValidateProduct(int productAttributeID)
        {
            ICProductAttributesController objProductAttributesController = new ICProductAttributesController();
            ICProductAttributesInfo objProductAttributesInfo = (ICProductAttributesInfo)objProductAttributesController.GetObjectByID(productAttributeID);
            if (objProductAttributesInfo != null)
            {
                ICTransferItemsInfo objICTransferItemsInfo = (ICTransferItemsInfo)ModuleObjects[TransferEntities.strICTransferItemsObjectName];
                objICTransferItemsInfo.FK_ICProductID = objProductAttributesInfo.FK_ICProductID;
                ICTransferItemsList.SetDefaultValuesFromProduct(objICTransferItemsInfo.FK_ICProductID);
                objICTransferItemsInfo.FK_ICFromStockID = ((ICTransfersInfo)MainObject).FK_ICFromStockID;
                objICTransferItemsInfo.FK_ICToStockID = ((ICTransfersInfo)MainObject).FK_ICToStockID;
                objICTransferItemsInfo.FK_ICTransitStockID = ((ICTransfersInfo)MainObject).FK_ICTransitStockID;
                objICTransferItemsInfo.FK_ICDepartmentID = objProductAttributesInfo.FK_ICDepartmentID;
                objICTransferItemsInfo.FK_ICProductGroupID = objProductAttributesInfo.FK_ICProductGroupID;
                objICTransferItemsInfo.FK_ICProductAttributeID = objProductAttributesInfo.ICProductAttributeID;
                objICTransferItemsInfo.ICTransferItemProductAttribute = objProductAttributesController.GetAttributeValueByProductAttributeID(objProductAttributesInfo.ICProductAttributeID);
                objICTransferItemsInfo.ICTransferItemProductSerialNo = objProductAttributesInfo.ICProductAttributeSerialNo;
                UpdateModuleObjectBindingSource(TransferEntities.strICTransferItemsObjectName);
            }
        }

        public void GenerateModuleItemsList()
        {
            foreach (ICTransferItemsInfo objReferenceTransferItemsInfo in lstICReferenceTransferItems)
            {
                TransferItemsEntity entTransferItem = new TransferItemsEntity();
                entTransferItem.GetFromBusinessObject(objReferenceTransferItemsInfo);
                entTransferItem.ICTransferItemID = 0;
                ICTransferItemsList.Add(entTransferItem);
            }
            ICTransferItemsList.GridControl.RefreshDataSource();
        }

        public override bool CompleteTransaction()
        {
            return CompleteShipment();
        }

        public override bool IsInvalidInventory()
        {
            String transactionType = String.Empty;
            if ((MainObject as ICTransfersInfo).ICTransferTypeCombo == TransferModule.cstTransferTypeTransfer)
            {
                foreach (TransferItemsEntity entItem in ICTransferItemsList)
                    entItem.FK_ICStockID = entItem.FK_ICFromStockID;
                transactionType = TransactionUtil.cstInventoryShipment;
            }
            else
            {
                foreach (TransferItemsEntity entItem in ICTransferItemsList)
                    entItem.FK_ICStockID = entItem.FK_ICToStockID;
                transactionType = TransactionUtil.cstInventoryReceipt;
            }
            return ICTransferItemsList.IsInvalidInventory(transactionType);
        }

        /// <summary>
        /// Update Transfer status to Post and update inventory stock from and stock transit
        /// </summary>
        /// <remarks> Hieunh_18/03/2010</remarks>
        private bool CompleteShipment()
        {
            ICTransfersInfo objICTransfersInfo = (ICTransfersInfo)MainObject;
            ICTransferItemsList.UpdateInventory(BusinessObject.DefaultAAStatus);
            //Update Transfer Status
            objICTransfersInfo.ICTransferStatusCombo = TransferModule.cstTransferStatusPost;
            objICTransfersInfo.AAUpdatedDate = DateTime.Now;
            objICTransfersInfo.AAUpdatedUser = THSApp.CurrentUser;
            UpdateMainObject();
            UpdateMainObjectBindingSource();
            return true;
        }

        /// <summary>
        /// Complete Transfer receipt,and update quantity of transit stock and to stock 
        /// </summary>
        /// <remarks>Hieunh_28/03/2010</remarks>
        public bool CompleteReceipt()
        {
            if (!IsInvalidInventory())
            {
                //Update reference transfer
                if (UpdateReferenceTransfer())
                {
                    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
                    {
                        try
                        {
                            SetPropertyChangeEventLock(false);
                            ICTransfersInfo objICTransfersInfo = (ICTransfersInfo)MainObject;
                            //Update inventory of receipt stock
                            ICTransferItemsList.UpdateInventory(BusinessObject.DefaultAAStatus);
                            //Update receipt transfer status
                            objICTransfersInfo.ICTransferStatusCombo = TransferModule.cstTransferStatusComplete;
                            objICTransfersInfo.AAUpdatedDate = DateTime.Now;
                            objICTransfersInfo.AAUpdatedUser = THSApp.CurrentUser;
                            UpdateMainObject();
                            UpdateMainObjectBindingSource();
                            scope.Complete();
                            return true;
                        }
                        catch (Exception)
                        {
                            scope.Dispose();
                        }
                        finally
                        {
                            SetPropertyChangeEventLock(true);
                        }
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// Switch to shipment branch, update inventory of transit stock and shipment transfer status
        /// </summary>
        /// <remarks>Hieunh_28/03/2010</remarks>
        public bool UpdateReferenceTransfer()
        {
            BRBranchsController objBRBranchsController = new BRBranchsController();
            ICTransfersController objICTransfersController = new ICTransfersController();
            ICTransferItemsController objICTransferItemsController = new ICTransferItemsController();
            ICStocksController objICStocksController = new ICStocksController();

            bool bUpdateComplete = false;
            ICTransfersInfo objICTransfersInfo = (ICTransfersInfo)MainObject;
            ICStocksInfo objICStocksInfo = (ICStocksInfo)objICStocksController.GetObjectByID(objICTransfersInfo.FK_ICFromStockID);
            BRBranchsInfo objShipmentBranchsInfo = (BRBranchsInfo)objBRBranchsController.GetObjectByID(objICTransfersInfo.FK_BRBranchID);
            try
            {
                THSApp.SwitchConnection(objShipmentBranchsInfo.BRBranchID);
                if (THSApp.TestCurrentConnection())
                {
                    //Update shipment transfer status
                    ICTransfersInfo objICReferenceTransfersInfo = (ICTransfersInfo)objICTransfersController.GetObjectByNo(objICTransfersInfo.ICTransferReference);
                    if (objICReferenceTransfersInfo != null)
                    {
                        if (objICReferenceTransfersInfo.ICTransferStatusCombo == TransferModule.cstTransferStatusPost)
                        {
                            objICReferenceTransfersInfo.ICTransferStatusCombo = TransferModule.cstTransferStatusComplete;
                            objICTransfersController.UpdateObject(objICReferenceTransfersInfo);

                            //Update inventory of transit stock
                            foreach (TransferItemsEntity itemEntity in ICTransferItemsList)
                            {
                                int iICInventoryTransitStockID = TransactionUtil.UpdateInventoryStock(
                                                           itemEntity.FK_ICProductID, itemEntity.FK_ICProductAttributeID, itemEntity.FK_ICTransitStockID,
                                                            itemEntity.ICTransferItemProductQty,
                                                            TransactionUtil.cstInventoryShipment);
                            }
                            bUpdateComplete = true;
                        }
                        else
                        {
                            MessageBox.Show("Can not complete the receipt because the shipment vote has been completed by another one.", "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return false;
                        }
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show(String.Format("Can not connect to {0}.", objShipmentBranchsInfo.BRBranchName), "#Message#", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            finally
            {
                THSApp.RollbackLocalConnection();
            }
            return bUpdateComplete;
        }

        private bool TransferItemIsComplete(ICTransferItemsInfo objICTransferItemsInfo)
        {
            foreach (TransferItemsEntity entTransferItem in ICTransferItemsList)
            {
                if (entTransferItem.ICTransferItemProductSerialNo == objICTransferItemsInfo.ICTransferItemProductSerialNo)
                {
                    if (entTransferItem.ICTransferItemProductQty == objICTransferItemsInfo.ICTransferItemProductQty)
                        return true;
                }
            }
            return false;
        }

        /// <summary>
        /// update inventorystock
        /// </summary>
        /// <remarks>HieuNH_27/03/2010</remarks>
        public override void UpdateInventory(ERPModuleItemsEntity entItems, string strUpdateStatus)
        {
            TransferItemsEntity itemEntity = (TransferItemsEntity)entItems;
            String strTransferType = ((ICTransfersInfo)MainObject).ICTransferTypeCombo;
            int iICStockID = 0;
            if (strTransferType.Equals(TransferModule.cstTransferTypeTransfer))
                iICStockID = itemEntity.FK_ICFromStockID;
            else if (strTransferType.Equals(TransferModule.cstTransferTypeTransferReceipt))
                iICStockID = itemEntity.FK_ICToStockID;

            #region--shipment--
            if (strTransferType.Equals(TransferModule.cstTransferTypeTransfer))
            {
                if (strUpdateStatus.Equals(BusinessObject.DefaultAAStatus))
                {
                    if (itemEntity.AAStatus == BusinessObject.DefaultAAStatus)
                    {
                        //Update inventory of shipment stock
                        int iICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                    itemEntity.FK_ICProductID, itemEntity.FK_ICProductAttributeID, iICStockID,
                                                    itemEntity.ICTransferItemProductQty,
                                                    TransactionUtil.cstInventoryShipment);
                        
                        //Update inventory of transit stock
                        int iICInventoryTransitStockID = TransactionUtil.UpdateInventoryStock(
                                                itemEntity.FK_ICProductID, itemEntity.FK_ICProductAttributeID, itemEntity.FK_ICTransitStockID,
                                                itemEntity.ICTransferItemProductQty,
                                                TransactionUtil.cstInventoryReceipt);
                    }
                }
                else if (strUpdateStatus == BusinessObject.DeletedAAStatus)
                {
                    if (itemEntity.AAStatus == BusinessObject.DefaultAAStatus)
                    {
                        //Update inventory of shipment stock
                        int iICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                    itemEntity.FK_ICProductID, itemEntity.FK_ICProductAttributeID, iICStockID,
                                                    -itemEntity.ICTransferItemProductQty,
                                                    TransactionUtil.cstInventoryShipment);

                        //Update inventory of shipment stock
                        int iICInventoryTransitStockID = TransactionUtil.UpdateInventoryStock(
                                                    itemEntity.FK_ICProductID, itemEntity.FK_ICProductAttributeID, itemEntity.FK_ICTransitStockID,
                                                    -itemEntity.ICTransferItemProductQty,
                                                    TransactionUtil.cstInventoryReceipt);
                    }
                }
            }
            #endregion

            #region--receipt--
            else if (strTransferType.Equals(TransferModule.cstTransferTypeTransferReceipt))
            {
                if (strUpdateStatus == BusinessObject.DefaultAAStatus)
                {
                    //Update inventory of receipt stock
                    if (itemEntity.AAStatus == BusinessObject.DefaultAAStatus)
                    {
                        int iICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                    itemEntity.FK_ICProductID, itemEntity.FK_ICProductAttributeID, iICStockID,
                                                    itemEntity.ICTransferItemProductQty,
                                                    TransactionUtil.cstInventoryReceipt);
                    }
                }
                else if (strUpdateStatus == BusinessObject.DeletedAAStatus)
                {
                    if (itemEntity.AAStatus == BusinessObject.DefaultAAStatus)
                    {
                        //Update inventory of receipt stock
                        int iICInventoryStockID = TransactionUtil.UpdateInventoryStock(
                                                    itemEntity.FK_ICProductID, itemEntity.FK_ICProductAttributeID, iICStockID,
                                                    -itemEntity.ICTransferItemProductQty,
                                                    TransactionUtil.cstInventoryReceipt);
                    }
                }
            }
            #endregion
        }
        
        #region --GENumbering--
        public override string GetMainObjectNo()
        {
            String strMainObjectNo = base.GetMainObjectNo();
            BRBranchsInfo objCurrentBranchsInfo = (BRBranchsInfo)new BRBranchsController().GetObjectByID(THSApp.CurrentCompanyInfo.FK_BRBranchID);
            GENumberingInfo objGENumberingsInfo = (GENumberingInfo)new GENumberingController().GetObjectByName(Module.Name);
            String strPrefix = String.Empty;
            if (objGENumberingsInfo != null)
            {
                strPrefix = objGENumberingsInfo.GENumberingPrefix;
                if (((ICTransfersInfo)MainObject).ICTransferTypeCombo.Equals(TransferModule.cstTransferTypeTransfer))
                {
                    strMainObjectNo = strMainObjectNo.Insert(strPrefix.Length, String.Format("O-{0}-", objCurrentBranchsInfo.BRBranchNo));
                }
                else if (((ICTransfersInfo)MainObject).ICTransferTypeCombo.Equals(TransferModule.cstTransferTypeTransferReceipt))
                {
                    strMainObjectNo = strMainObjectNo.Insert(strPrefix.Length, String.Format("I-{0}-", objCurrentBranchsInfo.BRBranchNo));
                }
            }
            return strMainObjectNo;
        }
        #endregion

        #region Functions for logging
        protected void LogTransferReceipt()
        {
            //For consistency, Roll-back local Connection
            THSApp.RollbackLocalConnection();

            int iICTransferLogID = CreateICTransferLogs();

            if (iICTransferLogID > 0)
            {
                CreateICTransferLogItems(iICTransferLogID);
            }

        }

        protected int CreateICTransferLogs()
        {
            ICTransferLogsController objICTransferLogsController = new ICTransferLogsController();

            ICTransferLogsInfo objICTransferLogsInfo = new ICTransferLogsInfo();
            objICTransferLogsInfo.ICTransferLogDate = ((ICTransfersInfo)MainObject).ICTransferDate;
            objICTransferLogsInfo.ICTransferReceiptNo = ((ICTransfersInfo)MainObject).ICTransferNo;
            objICTransferLogsInfo.ICReferenceTransferNo = ((ICTransfersInfo)MainObject).ICTransferReferenceNo;
            objICTransferLogsInfo.FK_ICFromStockID = ((ICTransfersInfo)MainObject).FK_ICFromStockID;
            objICTransferLogsInfo.FK_ICToStockID = ((ICTransfersInfo)MainObject).FK_ICToStockID;
            objICTransferLogsInfo.FK_ICTransitStockID = ((ICTransfersInfo)MainObject).FK_ICTransitStockID;

            return objICTransferLogsController.CreateObject(objICTransferLogsInfo);
        }

        protected void CreateICTransferLogItems(int iICTransferLogID)
        {
            ICTransferLogItemsController objICTransferLogItemsController = new ICTransferLogItemsController();

            foreach (TransferItemsEntity entTransferItems in ICTransferItemsList)
            {
                ICTransferItemsInfo objICTransferItemsInfo = (ICTransferItemsInfo)entTransferItems.SetToBusinessObject(THSUtil.GetTableNameFromBusinessObjectType(typeof(ICTransferItemsInfo)));
                ICTransferLogItemsInfo objICTransferLogItemsInfo = new ICTransferLogItemsInfo();
                THSUtil.CopyObjectItems(objICTransferItemsInfo,
                                         objICTransferLogItemsInfo,
                                         THSUtil.GetTableNameFromBusinessObjectType(typeof(ICTransferLogsInfo)));
                objICTransferLogItemsInfo.FK_ICTransferLogID = iICTransferLogID;

                objICTransferLogItemsController.CreateObject(objICTransferLogItemsInfo);
            }
        }
        #endregion
    }
}
